1 . 概述

梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最陡下降法,主要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长(学习率)距离点进行迭代搜索。

2 . SSE

3 . 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def plot_points(X, y):
admitted = X[np.argwhere(y==1)]
rejected = X[np.argwhere(y==0)]
plt.scatter([s[0][0] for s in rejected], [s[0][1] for s in rejected], s = 25, color = 'blue', edgecolor = 'k')
plt.scatter([s[0][0] for s in admitted], [s[0][1] for s in admitted], s = 25, color = 'red', edgecolor = 'k')

def display(m, b, color='g--'):
plt.xlim(-0.05,1.05)
plt.ylim(-0.05,1.05)
x = np.arange(-10, 10, 0.1)
plt.plot(x, m*x+b, color)


data = pd.read_csv('data.csv', header=None)
x = np.array(data[[0,1]])
y = np.array(data[2])
plot_points(x,y)
plt.show()


def sigmoid(x):
"""
sigmoid 计算
s(x) = 1/ (1 + e^-x)
"""
return 1 / (1 + np.exp(-x))

def output_formula(features, weights, bias):
"""
拟合函数
x : 特征
w : 权重
b : 偏移
y = s(Wx) + b
"""
return sigmoid(np.dot(features, weights) + bias)

def error_formula(y, output):
"""
错误率计算公式
y : 预测值
f : output_formula
error = -ylog(f)-(1-y)log(1-f)
"""
return np.dot(-y, np.log(output)) - np.dot((1 - y), np.log(1-output))
# return -y * np.log(f) - (1 - y) * np.log(1 - f)

def update_weights(x, y, weights, bias, learnrate=0.1):
"""
更新权重
"""
output = output_formula(x, weights, bias)
d_error = -(y - output)
weights -= learnrate * d_error * x
bias -= learnrate * d_error
return weights, bias

def train(features, targets, epochs, learnrate, graph_lines=False):

errors = []
n_records, n_features = features.shape
last_loss = None
weights = np.random.normal(scale=1 / n_features**.5, size=n_features)
bias = 0
for e in range(epochs):
del_w = np.zeros(weights.shape)
for x, y in zip(features, targets):
output = output_formula(x, weights, bias)
error = error_formula(y, output)
weights, bias = update_weights(x, y, weights, bias, learnrate)

# Printing out the log-loss error on the training set
out = output_formula(features, weights, bias)
loss = np.mean(error_formula(targets, out))
errors.append(loss)
if e % (epochs / 10) == 0:
print("\n========== Epoch", e,"==========")
if last_loss and last_loss < loss:
print("Train loss: ", loss, " WARNING - Loss Increasing")
else:
print("Train loss: ", loss)
last_loss = loss
predictions = out > 0.5
accuracy = np.mean(predictions == targets)
print("Accuracy: ", accuracy)
if graph_lines and e % (epochs / 100) == 0:
display(-weights[0]/weights[1], -bias/weights[1])


# Plotting the solution boundary
plt.title("Solution boundary")
display(-weights[0]/weights[1], -bias/weights[1], 'black')

# Plotting the data
plot_points(features, targets)
plt.show()

# Plotting the error
plt.title("Error Plot")
plt.xlabel('Number of epochs')
plt.ylabel('Error')
plt.plot(errors)
plt.show()